iT邦幫忙

2024 iThome 鐵人賽

DAY 3
0
Modern Web

web3 短篇集系列 第 3

使用 Foundry 學習 Solidity

  • 分享至 

  • xImage
  •  

最近正在學習使用 Foundry,它是一個開發智能合約的工具包,作為與區塊鏈進行簡單互動的工具也很方便,由於測試與部署都是使用 solidity,也能幫助熟悉與練習這門語言。

Foundry (鑄造廠) 包含四個主要指令: forge (鍛造), cast (投擲), anvil (鐵砧) 和 chisel (鑿子),目前比較常用的只有 forge 和 cast。

forge 可以用來部署合約 (create, script)、測試合約 (test)、檢查合約 (inspect);cast 可以用來查詢資料 (call)、送交易 (send)、轉換資料 (to-hex, to-ascii)等等。

這系列應該許多地方會用到 foundry 的指令來進行說明,有興趣的人可以下載玩玩看。

今日打算帶大家做以下幾件事:

  1. 安裝 foundry
  2. 建立新專案與安裝合約套件
  3. 環境設定
  4. 跑測試
  5. 部署合約
  6. 查詢鏈上資料與送交易

安裝 foundry

在 MacOS/Linux 環境底下可以使用

curl -L https://foundry.paradigm.xyz | bash

或參考官方文件 https://book.getfoundry.sh/getting-started/installation

安裝好後確認指令跑得動

forge -h
cast -h

建立專案與安裝合約

開一個新的資料夾,在資料夾內下:

forge init

forge install

openzepplin 是 solidity 的套件包,可以先把它安裝起來:

forge install OpenZeppelin/openzeppelin-contracts

或是貼上 github 專案的 url,它會以 git submodules 的形式儲存

forge install https://github.com/Vectorized/solady.git

solady 也是一個合約的套件包。

remappings

在根目錄新增 remappings.txt,並寫上

@openzeppelin/=lib/openzeppelin-contracts/

為了在 solidity 引用 openzeppelin 時比較符合慣例,例如:

import {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol";

環境設定

設定常用 rpc url 到環境變數

我自己為了方便下指令,如 --rpc-url=$sepolia,因此會把一些常用的 rpc url 放在全域的環境變數,例如 .zshrc 或 .bashrc 裡面:

export sepolia=https://ethereum-sepolia-rpc.publicnode.com
export mainnet=https://ethereum-rpc.publicnode.com

你可以在 https://publicnode.com/https://chainlist.org/ 找到需要的 rpc url,或是到 alchemy 申請 api key 使用更穩定的節點。

將私鑰放入 cast wallet

為了方便使用 cast 送交易,不想每次都複製貼上私鑰,也為了安全性,可以將私鑰使用 cast wallet 儲存在 ~/.foundry/keystore

查看目前已建立的錢包

cast wallet list

印出一把新的公私鑰對

cast wallet new

新增私鑰到錢包,名稱叫 dev,最後要設定密碼

cast wallet import dev --private-key=<0x...>

使用私鑰簽章

cast sign "hello" --account dev

刪除錢包的話就直接把檔案刪掉( ⚠️ 請確保錢包裡沒有重要資產,或私鑰已得到妥善保存 ‼️

rm ~/.foundry/keystore/dev

設定 .env

為了使用 forge script 部署合約,在專案的根目錄新增 .env 檔,填上一個部署合約要用的私鑰。

PRIVATE_KEY=0x
ETHERSCAN_API_KEY=

加入 ETHERSCAN_API_KEY 可以讓我們在部署合約時,使用 --verify 讓合約在 etherscan 上被驗證。

跑測試

-v: verbosity,愈多 v 會印出愈多資訊,-vv可以印出 logs。最多五個 -vvvvv
--match-path: 指定測試檔路徑,簡寫 --mp。(簡寫可查閱 forge test -h。)

forge test --mp test/Counter.t.sol -vvvv

--match-test: 指定 function name 進行測試,若測試 function 名稱相同就一起跑。

forge test --mt test_Increment

部署合約

使用 script 部署

修改預設的 script/Counter.s.sol,使用 .env 內的私鑰來部署合約。

function run() public {
    uint256 deployer = vm.envUint("PRIVATE_KEY");
    vm.startBroadcast(deployer);

    new Counter();

    vm.stopBroadcast();
}
forge script script/Counter.s.sol --rpc-url $sepolia --broadcast --verify

如果不加 --broadcast 就只會在本地跑測試,合約不會部署上鏈。

使用 forge create 部署

如果合約的 constructor 簡單或者沒有 parameter,用這個部署挺方便~

forge create --rpc-url $sepolia --account dev test/utils/send.sol:A

查詢資料與送交易

使用 cast call 查詢合約資料

cast call \
0x060dE2a6a809d45Acb441cAEfE511842f4F109CD \
"number()" \
--rpc-url $sepolia

使用 cast send 送交易

cast send --account dev \
--rpc-url $sepolia \
0x060dE2a6a809d45Acb441cAEfE511842f4F109CD \
"setNumber(uint256)" \
20

Reference


上一篇
認識 Calldata
下一篇
在區塊鏈上做一筆交易
系列文
web3 短篇集14
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言